#-*- coding:gb18030 -*-
#$Id: api.py 33089 2008-09-08 10:27:15Z jorwen@NETEASE.COM $

import  string, random
from django.db import transaction
from v4a.models import Vote, Question, ChoiceItem, VotesLog, ImageValidate 
from v4a.utils import ajax

__all__ = ['vote_datas', 'do_vote']


def _random_identifier(alphabet = string.ascii_letters + string.digits,length = 24):
	return "".join([random.choice(alphabet) for i in xrange(length)])


def vote_datas(request, vote_id):
	'''
		return example:
		{'return':'ok',
		 'vote':{'id':1, 'name':'test', 'desc':'vote description', 'css':'http://www.163.com/htdocs/css/example.css', 
				'auth': 1, 'votes_num':3244}
		 'questions': [{'id':3, 'type':1, 'content':'who is the hero?', 'min':1, 'max':1, 
						'choices':[{'id':1, 'content':'A', 'type':2}, ...]}, ],
		 'voter_info': [{'id':1, 'name':'Name', 'type': 0, 'min':2, 'max':233}, ...],
		}
	'''

	try:
		vote = Vote.objects.get(id=vote_id) 
	except Vote.DoesNotExist:
		return ajax.json_response({'return':'fail'})

	if vote.status != vote.VOTE_NORMAL:
		return ajax.json_response({'return':'forbidden'})

	result = {
		'return': 'ok',
		'vote': {'id':vote.id, 'name':vote.name, 'desc':vote.desc, 'css': vote.css, 'auth':vote.verify_type, 'votes':vote.votes_num},
		'questions': [],
		'voterinfo': []
	}
	for q in vote.question_set.all():
		question = {'id':q.id, 'type':q.qtype, 'content':q.content, 'min':q.min_answer_size, 'max':q.max_answer_size}
		if q.qtype == q.CHOICE_QUESTION:
			choices = []
			for c in q.choiceitem_set.all():
				choice = {'id':c.id, 'type':c.ctype, 'content':c.content, 'votes':c.votes_num}
				choices.append(choice)

			question['choices'] = choices

		result['questions'].append(question)
	
	for v in vote.voterinfo.all():
		voterinfo = {'id':v.id, 'name':v.name, 'type':v.dtype, 'min':v.min, 'max':v.max}
		result['voterinfo'].append(voterinfo)

	return ajax.json_response(result)
				

def _get_voterinfo(datas, vote):
	d = datas
	voterinfo = {}
	for v in vote.voterinfo.all():
		com_ret = {'ret':"", 'id':v.id, 'type':v.dtype, 'min':v.min, 'max':v.max}
		key = "voterinfo_%d"%(v.id)
		if not key in d.keys():
			com_ret['ret'] =  'invalid_access'
			return (False, com_ret)

		answer = d[key]
		if not answer:
			com_ret['ret'] = 'no_info_input'
			return (False, com_ret)


		if v.dtype == v.INTEGER:
			if not answer.isdigit():
				com_ret['ret'] =  'data_type_error'
				return (False, com_ret)

			tmp = int(answer)
			if tmp < v.min or  tmp > v.max:
				com_ret['ret'] =  'data_value_error'
				return (False, com_ret)

		if v.dtype == v.CHAR:
			if len(answer) < v.min or len(answer) > v.max:
				com_ret['ret'] =  'data_value_error'
				return (False, com_ret)

		voterinfo[v.id] = answer

	return (True, voterinfo)


def _get_answer(datas, vote, object_save_list):
	qs = Question.objects.select_related(depth=2).filter(vote__id=vote.id)
	question_idx = 0; question_list = {}
	for q in qs:
		question_idx += 1
		com_ret = {'ret':'', 'id':q.id, 'idx':question_idx, 'type':q.qtype}
		key = "question_%d"%(q.id)
		if not key in datas.keys():
			com_ret['ret'] = 'noanswer'
			return (False, com_ret) 

		if q.qtype == q.ESSAY_QUESTION:
			answer = datas.get(key) 
		else:
			answer = datas.getlist(key)

		answer_len = len(answer)
		if answer_len < q.min_answer_size or answer_len > q.max_answer_size:
			com_ret['ret'] = 'wrong_answer_num'
			return (False, com_ret)

		if q.qtype == q.CHOICE_QUESTION:
			for choice_id in answer:
				try:
					choice_item = ChoiceItem.objects.get(id=choice_id) 
				except ChoiceItem.DoesNotExist:
					com_ret['ret'] = 'invalid_access'
					return (ret, com_ret)

				if choice_item.ctype == ChoiceItem.WITH_INPUT:
					idx = answer.index(choice_id)
					key = "choice_input_%s"%(choice_id)
					if not datas.has_key(key):
						com_ret['ret'] = 'invalid_access'
						return (False, com_ret)

					if not datas[key]:
						com_ret['ret'] = 'no_choice_input'
						return (False, com_ret)

					answer[idx] = "%s-%s"%(choice_id, datas[key])

				choice_item.votes_num += 1
				object_save_list.append(choice_item)

			answer = '|'.join(answer)

		question_list[q.id] = answer
	return (True, question_list)


@transaction.commit_manually
def do_vote(request, vote_id):
	try:
		vote = Vote.objects.get(id=vote_id) 
	except Vote.DoesNotExist:
		transaction.rollback()
		return ajax.json_response({'ret':'invalida_access'})

	#if vote.status != vote.VOTE_NORMAL:
	#	transaction.rollback()
	#	return ajax.json_response({'ret':'forbidden'})


	object_save_list = []
	ret, val = _get_answer(request.POST, vote, object_save_list)
	if not ret:
		transaction.rollback()
		return ajax.json_response(val)
	question_list = val

	ret, val = _get_voterinfo(request.POST, vote) 
	if not ret:
		transaction.rollback()
		return ajax.json_response(val)
	voterinfo = val

	from v4a.utils.auth import  already_vote
	if already_vote(request, vote):
		transaction.rollback()
		return ajax.json_response({'ret':'already_vote'})

	from v4a.utils.auth import auth, get_username
	ret, vtype = auth(request, vote.verify_type)
	if not ret:
		transaction.rollback()
		return ajax.json_response({'ret':'auth_fail', 'vtype':vtype})


	all_data = (question_list, voterinfo)
	import base64, datetime
	votelog = VotesLog()
	votelog.vote = vote 
	votelog.answer = base64.encodestring(repr(all_data))

	votelog.time = datetime.datetime.now()
	votelog.user = get_username(request, vote.verify_type)  
	votelog.ip = request.META['REMOTE_ADDR']
	object_save_list.append(votelog)

	vote.votes_num += 1
	object_save_list.append(vote)

	try:
		for object in object_save_list:
			object.save()
	except:
		transaction.rollback()
		return ajax.json_response({'ret':'fail'})

	transaction.commit()
	return ajax.json_response({'ret':'ok'})


def get_image(request, path):
	import os
	if not os.path.exists(path):
		os.mkdir(path)

	from v4a.utils import captcha
	word, img = captcha.get_image()
	name = _random_identifier() + '.png'
	ip = request.META['REMOTE_ADDR']
	
	img.save("%s/%s"%(path,name), 'JPEG')
	object = ImageValidate(name=name, word=word, ip=ip)
	object.save()
	url = "http://%s/v4a/validator_image/%s/"%(request.META['HTTP_HOST'], name)
	return ajax.json_response({'url':url, 'name':name})


def show_image(request, name, path):
	from django.views import static
	return static.serve(request, name, path)

